//
// Created by Zsir on 2025/8/22.
//

#ifndef CHANNEL_H
#define CHANNEL_H

#include <functional>
#include <memory>

class EventLoop;

class Channel
{
public:
    using EventCallback = std::function<void()>;

    Channel(EventLoop *loop, int fd);

    ~Channel();

    void handleEvent();

    void setReadCallback(EventCallback cb)
    { readCallback_ = std::move(cb); }

    void setWriteCallback(EventCallback cb)
    { writeCallback_ = std::move(cb); }

    void setErrorCallback(EventCallback cb)
    { errorCallback_ = std::move(cb); }

    void setCloseCallback(EventCallback cb)
    { closeCallback_ = std::move(cb); }

    int fd() const
    { return fd_; }

    int events() const
    { return events_; }

    void set_revents(int revt)
    { revents_ = revt; }

    void enableReading()
    {
        events_ |= kReadEvent;
        update();
    }

    void disableReading()
    {
        events_ &= ~kReadEvent;
        update();
    }

    void enableWriting()
    {
        events_ |= kWriteEvent;
        update();
    }

    void disableWriting()
    {
        events_ &= ~kWriteEvent;
        update();
    }

    void disableAll()
    {
        events_ = kNoneEvent;
        update();
    }

    bool isNoneEvent() const
    { return events_ == kNoneEvent; }

    bool isWriting() const
    { return events_ & kWriteEvent; }

    bool isReading() const
    { return events_ & kReadEvent; }

    void remove();

private:
    void update();

    static const int kNoneEvent;
    static const int kReadEvent;
    static const int kWriteEvent;

    EventLoop *loop_;
    const int fd_;
    int events_;
    int revents_;

    EventCallback readCallback_;
    EventCallback writeCallback_;
    EventCallback errorCallback_;
    EventCallback closeCallback_;

    bool eventHandling_;
};

#endif // CHANNEL_H